<?php defined('SYSPATH') OR die('No direct access allowed.');

class GeraCodigo extends Core_Sintatico {

	private $identificadores;
	private $indice_identificadores;
	private $operadores;
	private $indice_operadores;
	private $strings;
	private $indice_strings;
	private $inteiros;
	private $indice_inteiros;
	private $reais;
	private $indice_reais;
	
	private $sintatico;
	private $codigoGerado;
	
	public function __construct($sintatico){
		$this->sintatico = $sintatico;
		$this->entrada = $sintatico->getEntrada();
		$this->geraListasDeTokens();
		//var_dump($this->strings);
		$this->codigoGerado = $this->geraCodigo($this->sintatico->getSaida());
		$this->filtraCodigoGerado();
	}
	
	public function getCodigo(){
		return $this->codigoGerado;
	}
	
	public function geraCodigo(&$saida){
		$result = '';
		if($saida!=null){
			$regra = array_shift($saida);
			//$producoes = $this->regras[$regra];
			$producoes = $this->traducao[$regra];
			$nome = $this->regrasByName[$regra];
			//$result = 'var '.$this->retiraMaiorEMenorQue($nome).$regra.' =  new YAHOO.widget.TextNode("'.$this->retiraMaiorEMenorQue($nome).'", '.$pai.', true);'."\n";
			for($i=0; $i< count($producoes); $i++) {
				$producao = $producoes[$i];
				if(in_array($producao, $this->regrasByName)){
					$result .= $this->geraCodigo($saida);
				}else{
					//echo $producao.' ';
					if($producao==self::t_IDENTIFICADOR){
						//$id++;
						$token = $this->getNextIdentificador();
						//var_dump($token);
						//$result .= ' '.$this->traducao[$regra][$i];
						if(is_object($token)){
							$result .= ' '.$token->getLexeme();
						}
					}else if($producao==self::t_COMPARACAO){
						$token = $this->getNextOperador();
						if(is_object($token)){
							$result .= ' '.$token->getLexeme();
						}
					}else if($producao==self::t_STRING){
						$token = $this->getNextString();
						if(is_object($token)){
							$result .= ' '.$token->getLexeme();
						}
					}else if($producao==self::t_INTEIRO){
						$token = $this->getNextInteiro();
						if(is_object($token)){
							$result .= ' '.$token->getLexeme();
						}
					}else if($producao==self::t_REAL){
						$token = $this->getNextReal();
						if(is_object($token)){
							$result .= ' '.$token->getLexeme();
						}
					}else if($producao==self::t_CARTESIANO){
						$result .= ' , ';
					}else{
						$result .= ' '.$this->traducao[$regra][$i];
					}
					
				}
			}
		}
		return $result;
	}
	public function filtraCodigoGerado(){
		$temSelect = false;
		$temFrom = false;
		$codigoFiltrado = array();
		$codigoDividido = explode(' ', $this->codigoGerado);
		for($i=0; $i<count($codigoDividido); $i++){
			if($codigoDividido[$i]=='î'){
				
			}else if($codigoDividido[$i]=='SELECT'){
				if(!$temSelect){
					$temSelect = true;
					$codigoFiltrado[] = $codigoDividido[$i];
				}
			}else if($codigoDividido[$i]=='FROM'){
				if(!$temFrom){
					$temFrom = true;
					$codigoFiltrado[] = $codigoDividido[$i];
				}
			}else if($codigoDividido[$i]=='*'){
				if($i==2){ // o * só pode aparecer como segunda plavra, apos o SELECT
					$codigoFiltrado[] = $codigoDividido[$i];
				}
			}else{
				$codigoFiltrado[] = $codigoDividido[$i];
			}
		}
		$this->codigoGerado = implode(' ', $codigoFiltrado);
		$this->codigoGerado = str_replace(' . ', '.', $this->codigoGerado);
		$this->codigoGerado = str_replace(' , ', ',', $this->codigoGerado);
		$this->codigoGerado .= ';';
	}
	
	
	public function geraListasDeTokens(){
		$this->indice_identificadores = 0;
		$this->indice_operadores = 0;
		$this->indice_strings = 0;
		$this->indice_inteiros = 0;
		$this->indice_reais = 0;
		for($i=0; $i<count($this->entrada); $i++){
			$token = $this->entrada[$i];
			if(is_object($token)){
				if($token->getId()==self::t_IDENTIFICADOR){
					$this->identificadores[] = $token;
				}else if($token->getId()==self::t_COMPARACAO){
					$this->operadores[] = $token;
				}else if($token->getId()==self::t_STRING){
					$this->strings[] = $token;
				}else if($token->getId()==self::t_INTEIRO){
					$this->inteiros[] = $token;
				}else if($token->getId()==self::t_REAL){
					$this->reais[] = $token;
				}
			}
		}
	}
	public function getNextIdentificador(){
		if($this->indice_identificadores<count($this->identificadores)){
			return $this->identificadores[$this->indice_identificadores++];
		}else{
			return null;
		}
	}
	public function getNextOperador(){
		if($this->indice_operadores<count($this->operadores)){
			return $this->operadores[$this->indice_operadores++];
		}else{
			return null;
		}
	}
	public function getNextString(){
		if($this->indice_strings<count($this->strings)){
			return $this->strings[$this->indice_strings++];
		}else{
			return null;
		}	
	}
	public function getNextInteiro(){
		if($this->indice_inteiros<count($this->inteiros)){
			return $this->inteiros[$this->indice_inteiros++];
		}else{
			return null;
		}	
	}
	public function getNextReal(){
		if($this->indice_reais<count($this->reais)){
			return $this->reais[$this->indice_reais++];
		}else{
			return null;
		}	
	}
    
} // End Sintatico